﻿using Microsoft.Xna.Framework;

namespace BattleFury.Time
{
	public class WorldTime
	{
		#region Properties

		private double _elapsed;

		public bool IsEnabled { get; set; }

		public int Year { get; set; }
		public int Month { get; set; }
		public int Day { get; set; }
		public int Hour { get; set; }
		public int Minute { get; set; }

		public int Sunrise { get; set; }
		public int Sunset { get; set; }

		public int MinutesInHour { get; set; }
		public int HoursInDay { get; set; }
		public int DaysInMonth { get; set; }
		public int MonthsInYear { get; set; }
		
		public bool MilitaryTime { get; set; }

		public double Interval { get; set; }

		public int TotalMinutes { get { return (Hour * MinutesInHour) + (Minute); } }
		public int MinutesInDay { get { return (MinutesInHour * HoursInDay); } }
		public bool IsDay { get { return (Hour >= Sunrise && Hour < Sunset); } }
		public bool IsNight { get { return ((Hour >= 0 && Hour < Sunrise) || (Hour >= Sunset)); } }
		public int Noon { get { return ((Sunset - Sunrise) / 2) + Sunrise; } }

		public double DayTick { get { return Minute + (Hour * MinutesInHour); } }

		public int Midnight
		{
			get
			{
				var ret = (((HoursInDay - Sunset) + Sunrise) / 2) + Sunset;
				if (ret >= HoursInDay) ret = 0;
				return ret;
			}
		}

		public double Tick
		{
			get
			{
				return Minute + (Hour * MinutesInHour) + (Day * HoursInDay * MinutesInHour) + (Month * DaysInMonth * HoursInDay * MinutesInHour) + (Year * MonthsInYear * DaysInMonth * HoursInDay * MinutesInHour);
			}
		}
		
		#endregion

		#region Initialization

		public WorldTime()
		{
			Year = 1;
			Month = 1;
			Day = 1;
			Hour = 0;
			Minute = 0;
			SetDefaultValues();
		}

		public WorldTime(int month, int day, int year, int hour, int minute)
		{
			Year = year;
			Month = month;
			Day = day;
			Hour = hour;
			Minute = minute;
			SetDefaultValues();
		}

		protected virtual void SetDefaultValues()
		{
			Interval = 0f;
			Sunrise = 6;
			Sunset = 18;

			MinutesInHour = 60;
			HoursInDay = 24;
			DaysInMonth = 30;
			MonthsInYear = 12;
			
			MilitaryTime = true;
			
			IsEnabled = true;
		}

		#endregion

		#region Methods

		public override string ToString()
		{
			return string.Format("Date: {0}/{1}/{2:0000} | Time: {3:00}:{4:00} | {5}", Month, Day, Year, Hour, Minute, IsDay ? "Day Time" : "Night Time");
		}

		public string ToTimeString()
		{
			var ret = string.Format("{0:00}:{1:00}", Hour, Minute);
			if (!MilitaryTime)
			{
				var hour = (Hour > 12 ? Hour - 12 : Hour);
				if (hour == 0) hour = 12;
				ret = string.Format("{0:0}:{1:00} {2}", hour, Minute, IsDay ? "am" : "pm");
			}
			return ret;
		}

		public string ToDateString()
		{
			return string.Format("Date: {0}/{1}/{2:0000}", Month, Day, Year);
		}

		public virtual void Update(GameTime gameTime)
		{
			_elapsed += gameTime.ElapsedGameTime.TotalMilliseconds;

			if (!IsEnabled) return;

			if (_elapsed >= Interval)
			{
				_elapsed -= Interval;
				Minute++;
				if (Minute >= MinutesInHour)
				{
					Hour++;
					Minute -= MinutesInHour;
				}
				if (Hour >= HoursInDay)
				{
					Day++;
					Hour -= HoursInDay;
				}
				if (Day > DaysInMonth)
				{
					Month++;
					Day = 1;
				}
				if (Month > MonthsInYear)
				{
					Year++;
					Month = 1;
				}
			}
		}

		public void AddHour()
		{
			Hour++;
			if (Hour >= HoursInDay)
			{
				Day++;
				Hour -= HoursInDay;
			}
			if (Day > DaysInMonth)
			{
				Month++;
				Day = 1;
			}
			if (Month > MonthsInYear)
			{
				Year++;
				Month = 1;
			}
		}

		public void Pause()
		{
			IsEnabled = false;
		}

		public void Unpause()
		{
			IsEnabled = true;
		}

		#endregion
	}
}